package pacientes;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import pessoas.PessoaInexistenteException;
import pessoas.RepositorioPessoas;
import pessoas.RepositorioPessoasBDR;
import planosSaude.PlanoSaude;
import planosSaude.PlanoSaudeNaoEncontradoException;
import planosSaude.RepositorioPlanosSaude;
import planosSaude.RepositorioPlanosSaudeBDR;
import planosSaude.RepositorioPlanosSaudeLista;
import util.IllegalArgumentException;
import util.PersistenceMechanismException;
import util.PersistenceMechanismRDBMS;
import util.RepositorioException;

public class RepositorioPacientesBDR implements RepositorioPacientes {

	private static RepositorioPacientesBDR instance = null;

	private PersistenceMechanismRDBMS pm;

	private RepositorioPacientesBDR() {
		try {
			pm = PersistenceMechanismRDBMS.getInstance();
			pm.connect();
		} catch (Exception ex) {
			// System.out.println(ex.getMessage());
			ex.printStackTrace();
		}
	}

	public synchronized static RepositorioPacientesBDR getInstance() {
		if (instance == null) {
			instance = new RepositorioPacientesBDR();
		}
		return instance;
	}

	public void atualizar(Paciente paciente)
			throws PacienteNaoEncontradoException, RepositorioException,
			IllegalArgumentException {
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			int i = statement.executeUpdate("UPDATE pacientes SET fk_plano = '" + paciente.getPlanoSaude().getCodigo()
					+ "', alergia = '" + paciente.getAlergia() 
					+ "' WHERE codigo = '" + paciente.getCodigo() + "'");
			RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
			rp.atualizar(paciente);

			if (i == 0) {
				throw new PacienteNaoEncontradoException(paciente.getCodigo());
			}
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} catch (PacienteNaoEncontradoException e) {
			throw new RepositorioException(e);
		} catch (PessoaInexistenteException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public boolean existe(long codigo) throws RepositorioException {
		boolean resposta = false;
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement
					.executeQuery("SELECT * FROM pacientes WHERE codigo = '" + codigo + "'");
			resposta = resultset.next();
			resultset.close();
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return resposta;
	}

	public RepositorioPacientes getPacientes() throws RepositorioException {
		RepositorioPacientes resposta = new RepositorioPacientesArray();
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement.executeQuery("SELECT * FROM pacientes");

			while (resultset.next()) {
				RepositorioPlanosSaude rm = new RepositorioPlanosSaudeLista();
				PlanoSaude planoSaude;
				try {
					planoSaude = rm.procurar(resultset.getLong("fk_plano"));
				} catch (PlanoSaudeNaoEncontradoException e) {
					planoSaude = null;
				}
				Paciente paciente = new Paciente(resultset.getLong("codigo"),
						null, null, null, null, null, null, null, null, null,
						planoSaude, resultset.getString("alergia"));
				resposta.inserir(paciente);
			}
			resultset.close();
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return resposta;
	}

	public IteratorPacientes getIterator() throws RepositorioException {
		return this.getPacientes().getIterator();
	}

	public void inserir(Paciente paciente) throws RepositorioException {
		try {
			Statement stmt = (Statement) pm.getCommunicationChannel();
			stmt.executeQuery("INSERT INTO pacientes (codigo, fk_plano, alergia) VALUES ('"
					+ paciente.getCodigo()+ "', '"
					+ paciente.getPlanoSaude()+ "', '" 
					+ paciente.getAlergia() + "')");

			RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
			rp.inserir(paciente);

		} catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}

	}

	public Paciente procurar(long codigo)
			throws PacienteNaoEncontradoException, RepositorioException {
		Paciente paciente = null;
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement
					.executeQuery("SELECT * FROM pacientes WHERE codigo = '" + codigo + "'");
			if (resultset.next()) {
				RepositorioPlanosSaude rPlano = RepositorioPlanosSaudeBDR.getInstance();
				PlanoSaude plano;
				try {
					plano = rPlano.procurar(resultset.getLong("fk_plano"));
				} catch (PlanoSaudeNaoEncontradoException e) {
					plano = null;
				}
				paciente = new Paciente(resultset.getLong("codigo"), null,
						null, null, null, null, null, null, null, null,
						plano,
						resultset.getString("alergia"));

				RepositorioPessoas rPessoa = RepositorioPessoasBDR.getInstance();
				rPessoa.complementarPessoa(paciente);

			} else {
				throw new PacienteNaoEncontradoException(codigo);
			}
			resultset.close();
			
		} catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} catch (PessoaInexistenteException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return paciente;

	}

	public RepositorioPacientes procurar(Paciente paciente) throws RepositorioException {
		IteratorPacientes pacientes = this.getIterator();
		RepositorioPacientes resposta = new RepositorioPacientesArray();
		while (pacientes.hasNext()) {
			Paciente pac = pacientes.next();
			if (pac.match(paciente)) {
				resposta.inserir(pac);
			}
		}
		return resposta;
	}

	public void remover(long codigo) throws PacienteNaoEncontradoException,
			RepositorioException {
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			int pac = statement.executeUpdate("DELETE FROM pacientes WHERE codigo='" + codigo + "'");
			if (pac == 0) {
				throw new PacienteNaoEncontradoException(codigo);
			}
			RepositorioPessoas rp = RepositorioPessoasBDR.getInstance();
			rp.remover(codigo);

		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} catch (PessoaInexistenteException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

}
